package com.gitee.feizns.quickstart.mybatis.plus.query;

import com.baomidou.mybatisplus.annotation.DbType;
import com.gitee.feizns.dynamic.Strings;

import java.util.EnumMap;
import java.util.function.Function;

/**
 * sql 工具类
 * @author feizns
 * @since 2023/4/2
 */
public abstract class SqlUtils {

    /**
     * 数据库类型对应的字段连接策略函数
     */
    private static final EnumMap<DbType, Function<String[], String>> joinMultipleColumnsStrategyByDbTypeFunction = new EnumMap<>(DbType.class);

    /**
     * 注册对应数据库的多字段连接函数
     * @param dbType db型
     * @param function 函数
     */
    public static void register(DbType dbType, Function<String[], String> function) {
        joinMultipleColumnsStrategyByDbTypeFunction.put(dbType, function);
    }

    static {
        register(DbType.MYSQL, SqlUtils::mysqlJoinMultipleColumns);
    }

    /**
     * 连接字段名策略
     * @param dbType db型
     * @return {@link Function}<{@link String[]}, {@link String}>
     */
    public static Function<String[], String> joinMultipleColumnsStrategy(DbType dbType) {
        Function<String[], String> strategy = joinMultipleColumnsStrategyByDbTypeFunction.get(dbType);
        if ( strategy == null )
            throw new UnsupportedOperationException(String.format("找不到%s的字段连接策略", dbType.getDesc()));
        return strategy;
    }

    /**
     * 将多个字段连接起来进行模糊查询（仅支持mysql）
     * <pre>{@code
     * //CONCAT(IFNULL(table_id,''),IFNULL(table_name,''))
     * System.out.println(joinMultipleFields("table_id", "table_name"));
     * }</pre>
     * @param columns 字段名列表
     * @return 将字段名连接后的sql
     */
    public static String mysqlJoinMultipleColumns(String... columns) {
        StringBuilder builder = new StringBuilder("CONCAT(");
        for (String column : columns) {
            builder.append(String.format("IFNULL(%s,'')", Strings.toSnakeCase(column)));
            builder.append(",");
        }
        builder.setLength(builder.length() - 1);
        builder.append(")");
        return builder.toString();
    }

    /**
     * 查询包装器
     * @return {@link String}
     */
    private static String concat(String... columns) {
        StringBuilder sb = new StringBuilder("CONCAT_WS(',',");
        for (String column : columns)
            sb.append(Strings.toSnakeCase(column)).append(",");
        sb.deleteCharAt(sb.length() - 1);
        return sb.append(")").toString();
    }

}
